using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.VSPowerToys.PackInstallerDataModel;

namespace Microsoft.VSPowerToys.PackInstaller
{
    public partial class SortItemControl : UserControl
    {
        /// <summary>
        /// Raised when user selects the sort method
        /// </summary>
        public event EventHandler<SortMethodSelectedEventArgs> SortMethodSelected;

        private ToolItem.SortByField sortMethodType;

        public ToolItem.SortByField SortMethodType
        {
            get { return sortMethodType; }
            set { sortMethodType = value; }
        }

        private string sortMethodName;

        /// <summary>
        /// Property to hold the string that is the name of the tag.
        /// </summary>
        public string SortMethodName
        {
            get { return this.sortMethodName; }
            set
            {
                this.sortMethodName = value;
                this.sortMethodNameLabel.Text = this.sortMethodName;
            }
        }

        private SortOrder currentSortOrder;

        public SortOrder CurrentSortOrder
        {
            get { return currentSortOrder; }
            set { currentSortOrder = value; }
        }


        /// <summary>
        /// This enum represents whether the tag is currently selected, the mouse is over it, or nothing.
        /// </summary>
        public enum SortMethodState
        {
            None,
            Hovered,
            Selected,
        }

        private SortMethodState currentSortMethodState;

        /// <summary>
        /// This property holds the current state for drawing.
        /// </summary>
        public SortMethodState CurrentSortMethodState
        {
            get { return this.currentSortMethodState; }
            set { SetSelectionState(value); }
        }

        public SortItemControl() : this(Strings.UnassignedSortMethodName, ToolItem.SortByField.None)
        {
            InitializeComponent();
        }

        /// <summary>
        /// Constructor, initializes the tag name and fonts.
        /// </summary>
        public SortItemControl(string sortMethodName, ToolItem.SortByField sortMethodType)
        {
            this.sortMethodType = sortMethodType;
            this.sortMethodName = sortMethodName;
            InitializeComponent();
            this.Font = SystemFonts.DialogFont;
            this.sortMethodNameLabel.Text = sortMethodName;
        }

        /// <summary>
        /// Method to set the selection to a particular value, and then refresh the control.
        /// </summary>
        private void SetSelectionState(SortMethodState selectionState)
        {
            this.currentSortMethodState = selectionState;
            switch(this.currentSortMethodState)
            {

                case SortMethodState.Selected:
                {
                    if (this.currentSortOrder == SortOrder.Descending)
                    {
                        this.sortMethodSelectedPictureBox.Image = Properties.Resources.Down_Arrow;
                    }
                    else
                    {
                        this.sortMethodSelectedPictureBox.Image = Properties.Resources.Up_Arrow;
                    }
                    break;
                }
                case SortMethodState.Hovered:
                {
                    this.sortMethodSelectedPictureBox.Image = Properties.Resources.Up_Arrow;
                    break;
                }
                case SortMethodState.None:
                default:
                {
                    this.sortMethodSelectedPictureBox.Image = null;
                    break;
                }
            }

            this.Refresh();
        }

        /// <summary>
        /// Selects the tag, and propagates an event.
        /// </summary>
        public void SelectSortMethod(SortOrder order)
        {
            if (this.currentSortMethodState != SortMethodState.Selected || this.currentSortOrder != order)
            {
                this.currentSortOrder = order;
                SetSelectionState(SortMethodState.Selected);
            }

            if (SortMethodSelected != null)
            {
                SortMethodSelected(this, new SortMethodSelectedEventArgs(this.sortMethodName, this.currentSortOrder));
            }
        }

        private void sortMethodNameLabel_Click(object sender, EventArgs e)
        {
            SortOrder newSortOrder = SortOrder.Ascending;

            if (this.CurrentSortMethodState == SortMethodState.Selected)
            {
                if (this.currentSortOrder == SortOrder.Ascending)
                {
                    newSortOrder = SortOrder.Descending;
                }
            }

            SelectSortMethod(newSortOrder);
        }

        private void sortMethodNameLabel_MouseEnter(object sender, EventArgs e)
        {
            if (this.currentSortMethodState != SortMethodState.Selected)
            {
                this.currentSortMethodState = SortMethodState.Hovered;
                this.sortMethodSelectedPictureBox.Image = Properties.Resources.Up_Arrow;
                this.Refresh();
            }
        }

        private void sortMethodNameLabel_MouseLeave(object sender, EventArgs e)
        {
            if (this.currentSortMethodState != SortMethodState.Selected)
            {
                this.currentSortMethodState = SortMethodState.None;
                this.sortMethodSelectedPictureBox.Image = null;
                this.Refresh();
            }
        }
    }

    /// <summary>
    /// An event arguments class for the event raised when the user clicks on the name of the tag.
    /// </summary>
    public class SortMethodSelectedEventArgs : EventArgs
    {
        [NonSerialized]
        private string sortMethodName;

        public string SortMethodName
        {
            get { return this.sortMethodName; }
            set { this.sortMethodName = value; }
        }

        [NonSerialized]
        private SortOrder newSortOrder;

        public SortOrder NewSortOrder
        {
            get { return this.newSortOrder; }
            set { this.newSortOrder = value; }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="task">Task that owns the event</param>
        public SortMethodSelectedEventArgs(string sortMethodName, SortOrder newOrder)
        {
            this.sortMethodName = sortMethodName;
            this.newSortOrder = newOrder;
        }
    }
}
